package com.fico.blaze;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

@Slf4j
@Data
public class XsdTemplate {
    private final String head = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
    private final String rootNodeStart = "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" version=\"3.0.0\">";
    private final String rootNodeEnd = "</xs:schema>";
    private final String complexTypeStart = "<xs:complexType>";
    private final String complexTypeEnd = "</xs:complexType>";
    private final String sequenceStart = "<xs:sequence>";
    private final String sequenceEnd = "</xs:sequence>";
    private LinkedHashMap<String ,String> EnToCnMap;
    private StringBuilder sb = new StringBuilder();

    //写xsd文件
    public void writeXsd(String path, JSONArray jsonArray) throws IOException {
        EnToCnMap = new LinkedHashMap<>();
        File file = new File(path);
        log.info("file path is : {}",file.getAbsolutePath());
        FileWriter fw = new FileWriter(file);
        String result = head;

        sb.append(head);
        sb.append("\n" + rootNodeStart);
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            buildXsd(jsonObject);
        }
        sb.append("\n" + rootNodeEnd);
        fw.write(sb.toString());
        fw.flush();
        fw.close();
    }

    public void buildXsd(JSONObject jsonObject) {

        //定义blaze类型映射xml类型
        Map<String, String> map = new HashMap<String, String>();
        map.put("real", "double");
        map.put("integer", "integer");
        map.put("string", "string");
        map.put("date", "date");
        map.put("timestamp", "dateTime");
        map.put("boolean", "boolean");

        //父节点
        String elementNode = jsonObject.getString("name");

        sb.append("\n\t\t" + "<xs:element name=\"" + elementNode + "\">");
        sb.append("\n\t\t\t" + complexTypeStart);
        JSONArray jsonArray = jsonObject.getJSONArray("properties");
        boolean sequnceFlag = false;
        JSONArray elementArray = new JSONArray();
        JSONArray attributeArray = new JSONArray();
        for (int i = 0; i < jsonArray.size(); i++) {
            if (jsonArray.getJSONObject(i).getString("type").contains("$")) {
                sequnceFlag = true;
                elementArray.add(jsonArray.getJSONObject(i));
            } else {
                attributeArray.add(jsonArray.getJSONObject(i));

            }

        }
        if (sequnceFlag) {
            sb.append("\n\t\t\t\t" + sequenceStart);
            for (int j = 0; j < elementArray.size(); j++) {
                JSONObject jsonObject1 = elementArray.getJSONObject(j);
                String elementName = jsonObject1.getString("xmlName");
                //如果是数组
                if (jsonObject1.getString("type").contains("array_of_")) {
                    sb.append("\n\t\t\t\t\t" + "<xs:element ref=\"" + elementName + "\" minOccurs=\"0\" maxOccurs=\"unbounded\" />");
                } else {
                    sb.append("\n\t\t\t\t\t" + "<xs:element ref=\"" + elementName + "\" minOccurs=\"0\" />");
                }

            }

            sb.append("\n\t\t\t\t" + sequenceEnd);
        }
        for (int k = 0; k < attributeArray.size(); k++) {
            JSONObject jsonObject1 = attributeArray.getJSONObject(k);
            String attibuteName = jsonObject1.getString("xmlName");
            String srlName = jsonObject1.getString("srlName");
            EnToCnMap.put(elementNode + "." + attibuteName, srlName);
            String type = jsonObject1.getString("type");
            type = map.get(type);
            sb.append("\n\t\t\t\t\t" + "<xs:attribute name=\"" + attibuteName + "\" type=\"xs:" + type + "\" use=\"optional\" />");
        }
        sb.append("\n\t\t\t" + complexTypeEnd);
        sb.append("\n\t\t" + "</xs:element>");
    }
}
